#include<iostream>
#include<unistd.h>
#include<stdlib.h>
#include<time.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<assert.h>
#include<vector>
#include"Task.hpp"
#define PROCESS_NUM 5
using namespace std;

int WaitCommand(int waitfd,bool& quit)//不发就阻塞
{
    uint32_t command=0;
    ssize_t s=read(waitfd,&command,sizeof(command));
    if(s==0)
    {
        quit=true;
        return -1;
    }
    assert(s==sizeof(uint32_t));
    return command;
}
void sendAndWakeup(pid_t who,int fd,uint32_t commands)
{
    write(fd,&commands,sizeof(commands));
    cout<<"main process:call process"<<who<<"execute"<<desc[commands]<<"through"<<fd<<endl;
}
int main()
{
    load();
    //pid:pipefd
    vector<pair<pid_t,int>> slots;
    for(int i=0;i<PROCESS_NUM;i++)
    {
        int pipefd[2]={0};
        int n=pipe(pipefd);
        assert(n==0);
        (void)n;

        pid_t id=fork();
        assert(id!=-1);
        if(id==0)
        {

            close(pipefd[1]);
            while(1)
            {
                bool quit=0;
                //pipefd[0]
                //命令
                int command=WaitCommand(pipefd[0],quit);//如果对面不发
                //执行对应的命令
                if(quit) break;
                if(command>=0&&command<handlersize())
                {
                    callbacks[command]();
                }
                else
                {
                    cout<<"非法命令"<<endl;
                }
            }
            exit(1);
        }
            close(pipefd[0]);
            slots.push_back(pair<pid_t,int>(id,pipefd[1]));

    }
    //父进程派发任务
    srand((unsigned long)time(nullptr)^getpid()^233231231231);
    while(1)
    {
        int command=rand()%handlersize();
        int choice=rand()%slots.size();
            //布置任务，把任务给一个指定进程 第一个参数是子进程的pid,第二个参数是管道文件的写
        sendAndWakeup(slots[choice].first,slots[choice].second,command);
        // int select,command;
        // cout<<"##########################################"<<endl;
        // cout<<"# 1.show functions  2.send functions     #"<<endl;
        // cout<<"##########################################"<<endl;
        // cout<<"<Please select>";
        // cin>>select;
        // if(select==1) showHandler();
        // else if(select==2)
        // {
        //     cout<<"Enter Your Command>>";
        //     cin>>command;
        //     int choice=rand()%slots.size();
        //     //布置任务，把任务给一个指定进程
        //     sendAndWakeup(slots[choice].first,slots[choice].second,command);
        // }
        sleep(1);
    }
    //关闭fd,结束所有进程
    for(const auto slot:slots)
    {
       close(slot.second);
    }
    //回收所有子进程信息
    for(const auto& slot:slots)
    {
        waitpid(slot.first,nullptr,0);
    }
}